/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#ifndef DEVMON_TOPOLOGY_DISCOVERY_H
#define DEVMON_TOPOLOGY_DISCOVERY_H

#include "device/csr.h"
#include "topology/device_topo.h"
#include <mc/engine.h>
#include <mutex>
#include <thread>
#include <atomic>
#include <memory>

// 拓扑发现超时时间配置
#if defined(BUILD_TYPE) && defined(BUILD_TYPE_DT) && BUILD_TYPE == BUILD_TYPE_DT
    // DT环境使用1s超时
    #define TOPOLOGY_DISCOVERY_TIMEOUT_MS 1000
#else
    // 生产环境使用60s超时
    #define TOPOLOGY_DISCOVERY_TIMEOUT_MS 60000
#endif

namespace devmon {

class topology_discovery {
public:
    static topology_discovery& get_instance(mc::engine::service* service = nullptr);
    
    ~topology_discovery();
    void normal_discovery();
    
    // 添加清理方法，用于安全关闭
    void cleanup();

private:
    explicit topology_discovery(mc::engine::service* service) 
        : m_service(service), m_is_active(true) {
    }
    topology_discovery(const topology_discovery&)            = delete;
    topology_discovery& operator=(const topology_discovery&) = delete;

    void listen_discovery_signal();
    
    void fetch_objects();
    
    void do_request_topology(const std::string& object_group_path);
    
    // 服务有效性检查
    bool is_service_valid() const;

    mc::engine::service*                                        m_service;
    std::mutex                                                  m_topology_mutex;  // 拓扑请求互斥锁
    std::mutex                                                  m_signal_queue_mutex;  // 信号队列访问互斥锁
    std::atomic<bool>                                           m_is_active;       // 标记对象是否处于活跃状态
    static std::once_flag                                       m_once_flag;       // 确保只初始化一次的标志
};

} // namespace devmon

#endif // DEVMON_TOPOLOGY_DISCOVERY_H